package com.qzxy.premiumhotelsystem.task;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.qzxy.premiumhotelsystem.common.constant.*;
import com.qzxy.premiumhotelsystem.domain.entity.Orders;
import com.qzxy.premiumhotelsystem.domain.entity.Rooms;
import com.qzxy.premiumhotelsystem.domain.entity.Vip;
import com.qzxy.premiumhotelsystem.domain.entity.VipOrders;
import com.qzxy.premiumhotelsystem.domain.pojo.Mail;
import com.qzxy.premiumhotelsystem.domain.vo.OrderInEmailVO;
import com.qzxy.premiumhotelsystem.domain.vo.OrderOutEmailVO;
import com.qzxy.premiumhotelsystem.domain.vo.VipEmailVO;
import com.qzxy.premiumhotelsystem.mapper.OrdersMapper;
import com.qzxy.premiumhotelsystem.mapper.RoomsMapper;
import com.qzxy.premiumhotelsystem.mapper.VipMapper;
import com.qzxy.premiumhotelsystem.mapper.VipOrdersMapper;
import com.qzxy.premiumhotelsystem.service.MailService;
import com.qzxy.premiumhotelsystem.utils.RedisUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;


@Component
@Slf4j
public class OrderRoomTask {

    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private RoomsMapper roomsMapper;
    @Resource
    private MailService mailService;

    @Value("${spring.mail.username}")
    private String sendMailer;


    /**
     * 处理超时订单
     */
    @Scheduled(cron = "0 * * * * ?")  // 每分钟触发一次
    @Transactional
    public void checkAndCancelUnpaidOrders() {
        log.info("处理预订超时订单");
        // 获取当前时间，减去 15 分钟
        Date fifteenMinutesAgo = DateUtil.offsetMinute(new Date(), -15);

        // 查找超过15分钟未支付的订单
        List<Orders> unpaidOrders = ordersMapper.findUnpaidOrders(fifteenMinutesAgo);

        for (Orders orders : unpaidOrders) {
            // 更新订单状态为已取消
            orders.setStatus(OrderStatusConstant.ORDER_CANCELLED);
            ordersMapper.updateById(orders);
            //更新房间为空闲
            Rooms rooms = Rooms.builder().roomId(orders.getRoomId())
                    .status(RoomStatusConstant.AVAILABLE)
                    .build();
            roomsMapper.updateById(rooms);

        }
    }




    /**
     * 临近入住时间2个小时，发送入住提醒
     * 临近退房时间2个小时，发送退房（是否续订）提醒
     */
    @Scheduled(cron = "0 0 * * * ?")  // 每小时检查并发送通知
    public void notifyVipExpiry() {
        log.info("检查临近入住时间的订单并发送通知");
        // 查询即将入住或退房的订单
        List<OrderInEmailVO> ordersCheckIn = ordersMapper.findOrdersWithUpcomingCheckIn();
        List<OrderOutEmailVO> ordersCheckOut = ordersMapper.findOrdersWithUpcomingCheckOut();

        for (OrderInEmailVO orderInEmailVO : ordersCheckIn) {
            String messageIn = String.format("尊敬的尾号%s客户，\n\n" +
                            "我们注意到您有一笔订单即将生效，\n" +
                            "- 入住时间：%s\n\n" +
                            "请您查看订单详情，提前准备好行程，我们期待您的光临。如有任何问题，请随时与我们联系。\n\n" +
                            "感谢您选择我们酒店，祝您旅途愉快！\n\n" +
                            "此致,\n臻品酒店管理团队", StrUtil.sub(orderInEmailVO.getTelephone(), -4, orderInEmailVO.getTelephone().length()),
                    DateUtil.formatDateTime(orderInEmailVO.getCheckInTime()));
            Mail mailIn = new Mail();
            mailIn.setText(messageIn);
            mailIn.setFrom(sendMailer);
            mailIn.setSubject("臻品酒店入住提醒");
            mailIn.setSendTo(orderInEmailVO.getEmail());
            mailService.sendSimpleMail(mailIn);
            log.info("发送成功");

        }

        log.info("检查临近退房时间的订单并发送通知");
        for (OrderOutEmailVO orderOutEmailVO : ordersCheckOut) {
            String messageOut = String.format("尊敬的尾号%s客户，\n\n" +
                            "我们注意到您有一笔订单即将到期，\n" +
                            "- 退房时间：%s\n\n" +
                            "请您查看订单详情，提前准备好行李，到一楼管理处进行退房。如有任何问题，请随时与我们联系。\n\n" +
                            "感谢您选择我们酒店，祝您生活愉快！\n\n" +
                            "此致,\n臻品酒店管理团队", StrUtil.sub(orderOutEmailVO.getTelephone(), -4, orderOutEmailVO.getTelephone().length()),
                    DateUtil.formatDateTime(orderOutEmailVO.getCheckOutTime()));
            Mail mail = new Mail();
            mail.setText(messageOut);
            mail.setFrom(sendMailer);
            mail.setSubject("臻品酒店退房提醒");
            mail.setSendTo(orderOutEmailVO.getEmail());
            mailService.sendSimpleMail(mail);
            log.info("发送成功");
        }

    }

}
